﻿using System;

namespace Aeon.Emulator.Sound.FM.Operators
{
    /// <summary>
    /// Emulates the snare drum OPL operator.
    /// </summary>
    internal sealed class SnareDrum : StandardOperator
    {
        /// <summary>
        /// Initializes a new instance of the SnareDrum operator.
        /// </summary>
        /// <param name="opl">FmSynthesizer instance which owns the operator.</param>
        public SnareDrum(FmSynthesizer opl)
            : base(0x14, opl)
        {
        }

        /// <summary>
        /// Returns the current output value of the operator.
        /// </summary>
        /// <param name="modulator">Modulation factor to apply to the output.</param>
        /// <returns>Current output value of the operator.</returns>
        public override double GetOperatorOutput(double modulator)
        {
            if(this.AdsrState == AdsrState.Off)
                return 0;

            double envelopeInDB = this.GetEnvelope();
            this.Envelope = Math.Pow(10, envelopeInDB / 10.0);

            this.Phase = opl.RhythmHighHatOperator.Phase * 2;
            double operatorOutput = GetOutput(modulator, this.Phase, this.SelectedWaveform);
            double noise = GetRandomDouble() * this.Envelope;

            if(operatorOutput / this.Envelope != 1 && operatorOutput / this.Envelope != -1)
            {
                if(operatorOutput > 0)
                    operatorOutput = noise;
                else if(operatorOutput < 0)
                    operatorOutput = -noise;
                else operatorOutput = 0;
            }

            return operatorOutput * 2;
        }
    }
}
